package com.weilele.library.websocket.okhttp

import com.weilele.mvvm.okHttpClient
import com.weilele.mvvm.utils.tryError
import com.weilele.library.websocket.BaseWebSocket
import com.weilele.library.websocket.WebSocketState
import com.weilele.mvvm.adapter.ignoreError
import com.weilele.mvvm.utils.logI
import okhttp3.Request
import okhttp3.Response
import okhttp3.WebSocket
import okhttp3.WebSocketListener
import okio.ByteString

internal class OKHttpWebSocketImpl(private val webSocketUrl: String) : BaseWebSocket() {
    private var webSocket: WebSocket? = null
    private val socketListener = object : WebSocketListener() {
        override fun onOpen(webSocket: WebSocket, response: Response) {
            super.onOpen(webSocket, response)
            logI { "WebSocket-->onOpen" }
            webSocketState = WebSocketState.Connected
        }

        override fun onFailure(webSocket: WebSocket, t: Throwable, response: Response?) {
            super.onFailure(webSocket, t, response)
            logI { "WebSocket-->onFailure:${t.message}" }
            webSocketState = WebSocketState.NoConnect
        }

        override fun onClosing(webSocket: WebSocket, code: Int, reason: String) {
            super.onClosing(webSocket, code, reason)
            logI { "WebSocket-->onClosing:${code},${reason}" }
        }

        override fun onMessage(webSocket: WebSocket, text: String) {
            super.onMessage(webSocket, text)
            onMessageCall?.invoke(text)
            logI { "WebSocket-->onMessage:${text}" }
        }

        override fun onMessage(webSocket: WebSocket, bytes: ByteString) {
            super.onMessage(webSocket, bytes)
            logI { "WebSocket-->onMessage:ByteString" }
            onMessageCall?.invoke(bytes)
        }

        override fun onClosed(webSocket: WebSocket, code: Int, reason: String) {
            super.onClosed(webSocket, code, reason)
            logI { "WebSocket-->onClosing:${code},${reason}" }
            webSocketState = WebSocketState.NoConnect
        }
    }


    override fun connect() {
        if (webSocketState == WebSocketState.NoConnect) {
            webSocketState = WebSocketState.Connecting
            val request: Request = Request.Builder().url(webSocketUrl).build()
            webSocket = okHttpClient.newWebSocket(request, socketListener)
        }
    }

    override fun disConnect() {
        super.disConnect()
        ignoreError { webSocket?.cancel() }
    }

    override fun sendMessage(msg: Any?): Boolean {
        return when (msg) {
            is String -> sendText(msg)
            is ByteArray -> sendByteArray(msg)
            else -> false
        }
    }

    private fun sendText(msg: String?): Boolean {
        return if (msg != null && webSocketState == WebSocketState.Connected) {
            if (webSocket?.send(msg) == true) {
                //发送成功
                true
            } else {
                //发送失败
                webSocketState = WebSocketState.NoConnect
                false
            }
        } else {
            false
        }
    }

    override fun sendMessageWaitConnect(msg: Any?) {

    }

    private fun sendByteArray(msg: ByteArray?): Boolean {
        return if (msg != null && webSocketState == WebSocketState.Connected) {
            if (webSocket?.send(ByteString.of(*msg)) == true) {
                //发送成功
                true
            } else {
                //发送失败
                webSocketState = WebSocketState.NoConnect
                false
            }
        } else {
            false
        }
    }


    override fun getRealWebSocket(): Any? {
        return webSocket
    }

}